#
# Writes a matrix into dcsc format  header:JC:CP:IR:NUM

import random
from numpy import linalg as LA
import numpy as np
import scipy.sparse as ss
import numpy.random as npr
import networkx as nx
import struct
import ctypes
import os, mmap

n = 160
p = 0.5
A = nx.gnp_random_graph(n, p)
A = nx.DiGraph(A)
A = nx.stochastic_graph(A)

B = ss.csc_matrix( nx.to_numpy_matrix(A))
del A
B = (B+B.T ) / 2

print "nnz: ", B.nnz
#print B.todense()

JC = sorted(list(set(B.tocsr().indices)))
CP = sorted(list(set(B.indptr)))
IR = B.indices
NUM = B.data

#print JC, "\n", CP, "\n", IR, "\n", NUM

size = 4*(4 + len(JC) + len(CP) + len(IR) + len(NUM))
filename =  "_".join(["dcsc_mat", "n"+str(n), "nnz" + str(B.nnz)])
filename = "../../data/" + filename
print filename

f = open(filename + ".bin", 'wb')
f.write(' ')
f.close()
f = open(filename + ".bin", 'r+b')
m = mmap.mmap(f.fileno(), 0,  access=mmap.ACCESS_WRITE)
m.resize(size)
print m.size()
m.seek(0)
bytes = ctypes.create_string_buffer(4)

offset = 0
for idx, val in enumerate([len(JC), len(CP) ,len(IR), len(NUM)]) :
	struct.pack_into('i', bytes, 0, val)
	m.write(bytes)
	offset += 4;

for idx, _list in enumerate(list([JC, CP, IR])) :
	for idx2, val in enumerate( _list ):
		struct.pack_into('i', bytes, 0, val )
		m.write(bytes)
		offset += 4

for val in NUM :
	struct.pack_into('f', bytes, 0, val )
	m.write(bytes)
	offset += 4

m.close()
f.close()
#filename =  "_".join(["dcsc_mat", "n"+str(n), "nnz" + str(B.nnz)])

ss 	= "N\t" + str(n) + "\n"
ss +=  "nnz0\t" + str(B.nnz) + "\n"
B1 = B.todense()
ss += "L1\t" + str(LA.norm(B1, 1)) + "\n"
ss += "L2\t" + str(LA.norm(B1, 2)) + "\n"
B1 = B.dot(B)
ss += "nnz1\t" + str(B.nnz) + "\n"
B1 = B1.todense()
ss += "L1\t" + str(LA.norm(B1, 1)) + "\n"
ss += "L2\t" + str(LA.norm(B1, 2)) + "\n"
finfo = open(filename + ".info", "w")
finfo.write(ss)
finfo.close()
print "packed NUM"

#filename += ".bin"
#f = open(filename, 'wb')
#f.write(bytes)